import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;

/**
 * Created by Bella on 13/04/2014.
 */
public class PageNode {

   private String nodeId;
   private Set<String> stringLinks;
   private Set<PageNode> inPageNode;
   private Set<PageNode> outPageNode;
   private int pageLength;
   private TreeMap<String, Integer> wordsInPage; //word and number of times in appearing in web page
   private HitsData hitsData;


    //constructor
    public PageNode(String domain) {
        nodeId= domain;
        stringLinks= new HashSet<String>();
        inPageNode= new HashSet<PageNode>();
        outPageNode= new HashSet<PageNode>();
        updateWordsInPageAndPageLength(domain);
        hitsData= new HitsData(domain);

    }

    /**
     * This function adds a new link to the web site
     * @param pageNode
     */
    public void addLink(PageNode pageNode) {
        stringLinks.add(pageNode.getNodeId());
    }

    /**
     * for a url this function parses the content of the web page.
     * @param address
     * @return a string of the web page content
     */
    public String getWebPageContent(String address) {

        String wordsInLine;
        StringBuilder stringbuilder = new StringBuilder();

        try {
            URL url = new URL(address);
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));


            while ((wordsInLine = br.readLine()) != null) {
                stringbuilder.append(wordsInLine);
                stringbuilder.append(System.getProperty("line.separator"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return stringbuilder.toString();
    }

    /**
     * this function receives an address of a web page and updates the fields wordsInPage and pageLength.
     * @param address
     * @return
     */
    private void updateWordsInPageAndPageLength(String address) {

        String urlContent =  getWebPageContent(address);
        String [] wordsArray = urlContent.split(" +"); //TODO handle end of sentence (,.)
        pageLength = wordsArray.length;
        wordsInPage= new TreeMap<String, Integer>();
        //for every word in page
        for (int i = 0; i < pageLength; i++) {
            //if we already found this word, increase its counter
            if (wordsInPage!=null && wordsInPage.containsKey(wordsArray[i])) {
                int value = wordsInPage.get(wordsArray[i]);
                value ++;
                wordsInPage.put(wordsArray[i], value);
            }
            //otherwise
            else {
                wordsInPage.put(wordsArray[i], 1);
            }

        }

    }



    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        PageNode pageNode = (PageNode) o;

        //if (!links.equals(pageNode.links)) return false;
        if (!nodeId.equals(pageNode.nodeId)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = nodeId.hashCode();
        result = 31 * result + stringLinks.hashCode();
        return result;
    }

    public TreeMap<String, Integer> getWordsInPage() {
        return wordsInPage;
    }

    public int getPageLength() {
        return pageLength;
    }

    public String getNodeId() {
        return nodeId;
    }

    public Set<String> getStringLinks() {
        return stringLinks;
    }

    @Override
    public String toString() {
        return "url=" + nodeId + "; " + "numOfWords=" + pageLength;
    }

    public void addInPageNode(PageNode pageNode) {
        inPageNode.add(pageNode);
    }

    public void addOutPageNode(PageNode pageNode) {
        outPageNode.add(pageNode);
    }

    public HitsData getHitsData() {
        return hitsData;
    }

    public Set<PageNode> getInPageNode() {
        return inPageNode;
    }

    public Set<PageNode> getOutPageNode() {
        return outPageNode;
    }

}
